const app = getApp();
const { appJson, socketurl } = app.siteInfo;
const _util = require('../util.js');
const { getUserInfo } = require('../../../utils/ws/wsxcx-opendata-sdk');
const wssUrl = socketurl;
const page_path = '/common/component/universal-card/pages/message';
let cardUserInfo = {};

Page({
  _unsendMsgs: [],
  _isOpen: false, // 默认关闭，无需卸载页面时再处理
  _isUnload: false,
  data: {
    msgList: [],
    defaultAvatar: './img/default-avatar.png',
    input: '',
    fromTpl: false,
    // needInfo: false,
    needMobile: false,
    showMobileGetter: false,
    page: 2,
    pageSize: 10,
    sendBtnStatus: 'msg',
    // sendTplMessage: true, // 是否发送模板消息开关
    showGetUserInfo: false,
    isWXWork: app.isWXWork,
  },

  // 从服务通知过来，会完整走一遍生命周期。
  onLoad() {
    // options传过来的
    // openid：当前用户的openID/会话双方己方的openID
    // to_openid ：会话双方对方的openID
    let that = this;
    let { openid, to_openid, m_id, scene, cardid, guestMobile } = this.options;
    this.setData({ openid, to_openid, m_id, scene, guestMobile: guestMobile || '' });

    // 获取手机号需先登录
    // _util.loginBeforeGetMobile().then(res => {});

    // 先检查用户是否绑定过信息
    let checkInfo = new Promise(function (resolve, reject) {
      app.util.request({
        url: 'card/api/is_up_user',
        data: {
          openid,
        },
        success: function (res) {
          resolve(res.data);
        },
        fail: res => {
          //
        },
      });
    });

    checkInfo.then(function(res) {
      // if (Number(res.data) === 0) that.setData({ needInfo: true }); // 需要用户信息授权，先授权；否则直接弹出手机号码获取窗口。
      // else that.setData({ needInfo: false });
      try {
        !guestMobile && that.checkUserTelephone(openid);
      } catch (error) {
        console.error(error);
      }
    }).then(function() {
      if (scene && scene === 'tpl') {
        that.setData({ fromTpl: true });
      }
      app.util.request({
        url: 'card/api/get_session_detail',
        data: {
          openid,
          m_id,
          page: '1',
          pagesize: '10',
          from_openid: to_openid,
        },
        success: function (res) {
          if (res.data.errno === 0) {
            const msgList = res.data.data.reverse();
            that.setData({
              msgList,
            });
            // msgList.length === 0 && that.sendMsg();
            that.pageScrollToBottom();
          }
        },
        fail: res => {
          //
        },
      });
    });

    // 可以获取的名片人的名片信息，有此名片信息，意味着可以发送模板或者接收模板
    this.getMasterInfo(scene, cardid).then(res => {
      let masterOpenid = that.data.masterInfo && that.data.masterInfo.openid;
      // let toOpenID = that.data.to_openid;
      let guestOpenid = that.data.openid; // 对话本人的openid
      // let { msgList } = that.data;

      that.setData({
        isMaster: masterOpenid === guestOpenid ? true : false,
        sendBtnStatus: masterOpenid === guestOpenid ? 'tpl' : 'msg',
      }, () => {
        if (that.data.isMaster) {
          that.getGuestMobile(to_openid);
          that.data.fromTpl && that.getGuestRecord(to_openid, cardid);
          that.getGuestCardinfo(this.data.to_openid);
        }
      });
    }).catch(e => {
      // TODO
      wx.showToast({
        title: '缺少名片信息',
        icon: 'none',
      });
    });
    this.wssInit();
    this.checkAuth();

  },

  onShow() {
    // const that = this;
    let fromOpenid = app.globalData.fromOpenid || '';
    let { openid } = this.data;

    if (fromOpenid && openid && fromOpenid !== openid) {
      app.util.request({
        url: 'card/api/bind_from',
        data: {
          openid,
          fromOpenid,
          share_scene: '3',
        },
      });
    }

    getSystemInfo.call(this);  // 适配老安卓的光标键盘间距
  },

  // 页面卸载时，关闭当前聊天连接。
  onUnload() {
    this._isUnload = true;
    this._isOpen && wx.closeSocket();
  },

  onPullDownRefresh: function () {
    const that = this;
    const { openid, to_openid, m_id, msgList, page, pageSize } = this.data;
    if (Number(msgList) <= 10) {
      return false;
    }
    app.util.request({
      url: 'card/api/get_session_detail',
      data: {
        openid,
        m_id,
        page,
        pagesize: pageSize,
        from_openid: to_openid,
      },
      success: function (res) {
        wx.stopPullDownRefresh();
        if (res.data.errno === 0) {
          const newMsgList = res.data.data;
          if (newMsgList.length > 0) {
            that.setData({
              msgList: [...(msgList.reverse()), ...newMsgList].reverse(),
              page: Number(page) + 1,
            });
          } else {
            wx.showToast({
              title: '没有更多了',
              icon: 'none',
            });
          }
        }
      },
      fail: function() {
        wx.stopPullDownRefresh();
      },
    });
  },

  submitMsg: throttle(function(e) {
    this.sendMsg(e);
  }, 1000),

  sendMsg(e) {
    let { input: content, openid, to_openid, m_id, sendBtnStatus, masterInfo } = this.data;
    let spaceContentCheck = new RegExp('^[ ]+$'); // 空格串判断
    if ((content === '' || spaceContentCheck.test(content)) && sendBtnStatus === 'msg' && e) {
      wx.showToast({
        title: '内容不能为空',
        icon: 'none',
      });
      return;
    }

    if (!e) {
      content = '';
      sendBtnStatus = 'tpl';
    }

    if (sendBtnStatus === 'tpl' && masterInfo) {
      // 用来发模板消息的，比较早的数据格式
      content = `你好，我是${masterInfo.company ? (masterInfo.company + '的') : ''}${masterInfo.name}。留言可能无法及时回复，您还可以通过电话直接联系我：${masterInfo.mobile}`;
    }
    this.doSendMessage(openid, m_id, to_openid, content, page_path, sendBtnStatus);
  },

  // 自动发模板
  sendTemplate(){
    let { input: content, openid, to_openid, m_id, sendBtnStatus, masterInfo } = this.data;
    content = '留言提醒';
    sendBtnStatus = 'tpl'
    this.doSendMessage(to_openid, m_id, openid, content, page_path, sendBtnStatus);
  },

  // 执行发送消息的方法
  doSendMessage(openid, m_id, to_openid, content, page_path, type) {
    let { name, company, position, wechatId, mobile } = this.data.masterInfo;
    let cardInfo = { name, company, position, wechatId, mobile };
    this.setData({ sendInfo: { openid, m_id, to_openid, content, page_path, type }});
    this.sendMessageAjax('1'); // 1在线

    let avatarUrl = cardUserInfo.avatarUrl;
    let socketMsg = { // socket消息格式
      uid: openid,
      to: to_openid,
      msg: content,
      contentType: 0,
      type: 1,
      custom: { openid, avatarUrl, type, cardInfo }, // 传递openid值，用于判断当前聊天窗口的信息是否为该联系人
    };

    // socket同时发送一遍进行推送消息。
    // 添加当前链接状态的判断
    if (this._isOpen) {
      wx.sendSocketMessage({
        data: JSON.stringify(socketMsg),
        success: res => {
          if (res.errMsg === 'sendSocketMessage:ok') {
            console.log('推送成功');
          } else {
            console.log('推送失败');
          }
        },
        fail: err => {
          console.log(err + '推送失败');
        },
      });
    } else {
      this._unsendMsgs.push(JSON.stringify(socketMsg));
    }

  },

  // 接口发送消息存入数据库
  sendMessageAjax(online) {
    const that = this;
    const { isMaster } = this.data;
    let msgList = this.data.msgList;
    let { name, company, position, wechatId, mobile } = this.data.masterInfo;
    let cardInfo = { name, company, position, wechatId, mobile };
    let { openid, m_id, to_openid, content, page_path, type } = this.data.sendInfo;
    app.util.request({
      url: 'card/api/post_message',
      data: {
        openid,
        to_openid,
        content,
        page_path,
        type,
        online,
        formid:''
      },
      success: function (res) {
        if (Number(res.data.errno) === 0 && online === '1') {
          that.setData({ input: '', sendBtnStatus: isMaster ? 'tpl' : 'msg' });
          wx.setStorageSync('vistorFirstChart', 0)
          // let createtime = app.util.formatTime(new Date() / 1000);
          // let newMsg = {
          //   m_id,
          //   type,
          //   content,
          //   card_info: isMaster ? cardInfo : that.data.myBasicCardInfo,
          //   createtime,
          //   is_see: '1',
          //   is_my: 1,
          //   nickname: that.data.myBasicInfo && that.data.myBasicInfo.nickname,
          //   deleted: '0',
          //   openid: openid,
          //   avatar: that.data.myBasicInfo && that.data.myBasicInfo.avatar,
          // };
          // msgList.push(newMsg);
          // that.setData({ msgList });
          // that.pageScrollToBottom();
          that.onLoad();
        }
      },
    });
  },

  getUserInfo(e) {
    const that = this;
    const { openid, needMobile } = this.data;
    const data = e.detail;
    if (data.errMsg === 'getUserInfo:ok') {
      const userInfo = e.detail.userInfo;
      cardUserInfo = e.detail.userInfo;
      // this.setData({ needInfo: false });
      app.util.request({
        url: 'card/api/up_user_info',
        data: {
          openid,
          nickname: userInfo.nickName,
          avatar: userInfo.avatarUrl,
        },
        cachetime: 0,
      });
      wx.showToast({
        title: '授权成功',
        success: function() {
          if (needMobile) {
            console.log('获取手机号弹窗： getUserInfo');
            setTimeout(function() {
              that.setData({ showMobileGetter: true });  // 显示获取手机号码的弹窗
            }, 1000);
          }
        },
      });
    } else {
      wx.showToast({
        title: '授权失败',
        icon: 'none',
        success: function () {
          setTimeout(function () {
            let url = appJson[0].homePage;
            app.util.navigateTo(url);
          }, 1000);
        },
      });
    }
  },

  getInput(e) {
    const input = e.detail.value;
    this.setData({ input, sendBtnStatus: 'msg' });
  },

  onFocus(e) {
    this.setData({ sendBtnStatus: 'msg' });
  },

  onBlur(e) {
    const { isMaster, input } = this.data;
    isMaster && !input && this.setData({ sendBtnStatus: 'tpl' });
  },

  // 获取手机号码
  getMobile(e) {
    let that = this;
    const { openid } = this.data;
    const { encryptedData, iv } = e.detail;
    app.util.request({
      url: 'card/api/get_phone_number',
      data: { encryptedData, iv, openid },
      method: 'POST',
      catchtime: 0,
      success(res) {
        const guestMobile = res.data.data.phoneNumber || this.data.guestMobile || '';
        // wx.setStorageSync({
        //   'phone-number-for-card': guestMobile,
        // });
        console.log('手机号解密接口失败：', JSON.stringify(res.data));
        // console.log('用户的opneid：', openid);
        console.log('手机号带解密数据', JSON.stringify(e.detail));
        that.setData({
          guestMobile,
          needMobile: false,
          showMobileGetter: false,
        });
      },
      fail: function(e) {
        console.log('手机号解密接口失败：', JSON.stringify(e));
        that.setData({
          showMobileGetter: false,
        });
      },
    });
  },

  // 拒绝获取手机号码
  refuseGiveMobile() {
    this.setData({ showMobileGetter: false });
  },

  // 滚动至页面底部
  pageScrollToBottom: function () {
    // const that = this;
    if (this.data.msgList.length > 0) {
      wx.createSelectorQuery()
        .select('#container')
        .boundingClientRect(function(rect) {
          wx.pageScrollTo({
            scrollTop: rect.height,
            duration: 0, // android机子滑动会从上往下，动画时长为0可以暂时解决，不过体验不太好
          });
        })
        .exec();
    } else {
      return false;
    }
  },

  returnHome(e) {
    let url = appJson[0].homePage;
    app.util.navigateTo(url);
  },

  // 获取名片信息，对访客来说，这是名片主人的名片信息；对名片用户来说，这里是自己的名片信息
  getMasterInfo(scene, cardid) {
    let that = this;

    // 从模板消息进入，依据路径携带的cardid获取名片信息。
    return new Promise((resolve, reject) => {
      if (Number(cardid) >= 0) {
        app.util.request({
          url: 'card/api/get_card_byid',
          data: { id: cardid },
          success: function(res) {
            if (Number(res.data.errno) === 0) {
              const masterInfo = res.data && res.data.data;
              that.setData({ masterInfo });
              console.log('======vistorFirstChart=======', wx.getStorageSync('vistorFirstChart'))
              wx.getStorageSync('vistorFirstChart') != 0 && that.sendTemplate();
              resolve(masterInfo);
            } else {
              reject(new Error(false));
            }
          },
          fail: function(err) {
            reject(err);
          },
        });
      } else {
        // 名片主人逐页进入或客人从分享进入，都已缓存名片信息。
        let masterInfo = wx.getStorageSync('masterInfo');
        if (masterInfo instanceof Object && !(masterInfo instanceof Array) && Object.keys(masterInfo).length > 0) {
          this.setData({ masterInfo });
          resolve(masterInfo);
        } else {
          reject(new Error(false));
        }
      }
    });
  },

  // 拨打名片主人的电话
  callMe(e) {
    let that = this;
    let phoneNumber = e.currentTarget.dataset.phone || '';
    // const exp = app.util.phoneExp.mobile;
    if (phoneNumber) {
      wx.makePhoneCall({
        phoneNumber,
        success: res => {
          res.errMsg === 'makePhoneCall:ok' && app.util.request({
            url: 'card/api/make_phone_call',
            data: {
              openid: that.data.openid,
              targetOpenid: that.data.to_openid,
            },
            complete: res => {
              console.log(res);
            },
          });
        },
      });
    } else {
      wx.showToast({
        title: '该用户没留下手机号码',
        icon: 'none',
      });
    }
  },

  // 拨打访客的电话
  callBack(e) {
    // const exp = app.util.phoneExp.mobile;
    let { guestMobile: phoneNumber } = e.currentTarget.dataset;
    const { isMaster } = this.data;

    if (isMaster && phoneNumber) {
      wx.makePhoneCall({
        phoneNumber,
      });
    }
  },

  previewQrcode(e) {
    const qrcode = e.currentTarget.dataset.qrcode;
    wx.previewImage({
      urls: [qrcode],
    });
  },

  // 加名片主人为微信好友
  addWechat(e) {
    let wechatId;
    let mobile;
    if (this.data.isMaster) {
      wechatId = this.data.getGuestCardinfo ? this.data.getGuestCardinfo.wechatId : '';
      mobile = this.data.guestMobile1;
    } else {
      wechatId = this.data.masterInfo.wechatId;
      mobile = this.data.masterInfo.mobile;
    }
    wechatId = wechatId || mobile;
    const exp = /^[^\s]*$/;
    if (wechatId && exp.test(wechatId)) {
      wx.setClipboardData({
        data: wechatId,
        success: (result) => {
          wx.showToast({
            title: '已复制对方微信号',
            icon: 'none',
          });
        },
      });
    } else {
      wx.showToast({
        title: '没有留下有效的微信号',
        icon: 'none',
      });
    }
  },

  // 访客留下自己的电话
  leaveYourMobile(e) {
    const { openid, to_openid, m_id, guestMobile } = this.data;

    let type = 'tel';
    let content = guestMobile;

    if (content && content !== 'undefined') {
      this.doSendMessage(openid, m_id, to_openid, content, page_path, type);
    } else {
      console.log('获取手机号弹窗： leaveYourMobile');
      this.setData({ showMobileGetter: true });
    }
  },

  leaveSelfMobile(e) {
    const { openid, to_openid, m_id, guestMobile, masterInfo, isMaster } = this.data;

    let type = 'tel';
    let content = isMaster ? masterInfo.mobile : guestMobile;

    if (content && content !== 'undefined') {
      this.doSendMessage(openid, m_id, to_openid, content, page_path, type);
    } else {
      this.setData({ showMobileGetter: true });
    }
  },

  // bugs:
  // 1. 上次操作没结束，进行了下一次
  // 2. 未连接成功
  wssInit() {
    let that = this;
    let loginMsg = { // 一开始的登录信息
      type: 0,
      uid: that.data.openid,
      to: that.data.to_openid,
      msg: 'login',
      contentType: 0,
    };
    this.connectWss();
    // 连接失败，如果监听链接成功则后续将进入socket close事件中，这时候是否自动重连？
    wx.onSocketError(function (res) {
      console.log('socket错误事件：', res);
      that._isOpen = false;
      // that.setData({
      //   isOpen: false,
      //   // statusMsg: '已断开',
      // });
    });
    // 监听连接成功
    wx.onSocketOpen(function (res) {
      console.log('socket连接打开成功');
      that._isOpen = true;
      // that.setData({
      //   isOpen: true,
      //   // statusMsg: '已连接',
      // });
      // that.handleGetChatList();
      // 发送未发送的socket信息。 用来下发通知和下发及时聊天界面的聊天记录。
      if (that._unsendMsgs) {
        for (let i = 0; i < that._unsendMsgs.length; i++) {
          wx.sendSocketMessage({
            data: that._unsendMsgs[i],
          });
        }
        that._unsendMsgs = [];
      }

      // 监听接收消息
      wx.onSocketMessage(function (res) {
        let res_data = {};
        if (isJsonStr(res.data)) {
          res_data = JSON.parse(res.data);
          console.log('收到服务器socket JSON消息：', res_data);
        } else {
          console.log('收到服务器socket消息：', res);
        }

        // 从接口获取最新信息，直接连接在最新的list上
        if (res_data.errcode === 0) {  // 好友在线
          let { msgList } = that.data;
          let { time, content, custom } = res_data;
          let fromOpenId = custom.openid || '';
          let newMsg = {
            openid: that.data.to_openid,
            type: custom.type || 'msg',
            card_info: custom.cardInfo,
            content,
            createtime: time,
            is_see: '1',
            is_my: 0,
            avatar: custom.avatarUrl,
            nickname: '',
            deleted: '0',
          };

          if (fromOpenId === that.data.to_openid) { // 获取到信息的openid是当前聊天窗口的openid，则显示消息
            msgList.push(newMsg);
            that.setData({ msgList });
            that.pageScrollToBottom();
            // setTimeout(function () {
            //   that.pageScrollToBottom();
            // }, 500);
          }
        } else if (res_data.errcode === -1) {  // 好友不在线
          console.log('对方不在线');
          that.sendMessageAjax('2'); // 2不在线
          // 状态
          // type：2心跳
          // type：3离线
          // if (res_data.type === 3 && that.data.sendTplMessage) {
          // }
        }
      });

      // console.log(loginMsg);
      // 发送登录信息
      wx.sendSocketMessage({
        data: JSON.stringify(loginMsg),
        success: res => {
          console.log('socket登录消息发送成功', res);
        },
        fail: err => {
          console.log('socket登录消息发送失败', err);
        },
      });

      // 监听socket关闭
      wx.onSocketClose(() => {
        console.log('socket 连接关闭');
        that._isOpen && !that._isUnload && that.connectWss();
      });
    });
  },

  // socket占位，上一次未完成，这一次又进行，会报错：one or more reserved bits are on
  connectWss: function () {
    // this.setData({
    //   statusMsg: '连接中。。。',
    // });
    console.log('socket连接中...');
    connect();
  },

  // 判断用户手机号
  checkUserTelephone(openid) {
    const that = this;
    app.util.request({
      url: 'card/api/is_up_user',
      data: {
        openid,
        type: 'is_phone',
      },
      success: function (res) {
        if (Number(res.data.data) === 0) {
          that.setData({
            showBindMobile: true,
          });
        } else if (Number(res.data.data) === 1) {
          that.setData({
            myBasicInfo: res.data.uinfo || {},
            myBasicCardInfo: res.data.card_info || {},
            guestMobile: res.data.uinfo.phone,
          });
        }
        cardUserInfo.avatarUrl = res.data.uinfo && res.data.uinfo.avatar;
      },
    });
  },

  getUserMobile(e) {
    let mobile = e.detail.mobile || '';
    this.setData({ guestMobile: mobile });
  },

  useMsgTool(e) {
    let { type } = e.currentTarget.dataset;
    type === 'wechat' && this.addWechat(e);
    type === 'call' && this.callMe(e);
    type === 'giveMobile' && this.leaveSelfMobile();
  },

  getGuestMobile(openid) {
    const that = this;
    app.util.request({
      url: 'card/api/is_up_user',
      data: {
        openid,
        type: 'is_phone',
      },
      success: function (res) {
        if (Number(res.data.data) === 0) {
          that.setData({
            guestMobile1: '',
          });
        } else if (Number(res.data.data) === 1) {
          that.setData({
            guestMobile1: res.data.uinfo.phone,
          });
        }
      },
    });
  },

  getGuestCardinfo(openid) {
    app.util.request({
      url: 'card/api/have_cared',
      data: { openid },
      success: res => {
        res.data.errno === 0 && res.data.data && app.util.request({
          url: 'card/api/red_card',
          data: { openid, id: res.data.data.id },
          success: (res) => {
            if (Number(res.data.errno) === 0) {
              this.setData({ getGuestCardinfo: res.data.data });
            }
          },
        });
      },
      fail: (res) => {
        //
      },
    });
  },

  getGuestRecord(openid, cardId) {
    app.util.request({
      url: 'card/api/get_record_id',
      data: {
        openid,
        cardid: cardId,
      },
      success: res => {
        if (Number(res.data.errno) === 0) {
          this.setData({
            guestRecord: res.data.data,
          });
        }
      },
      fail: err => {
        console.error(err);
      },
    });
  },

  onAvatarTapped(e) {
    const item = e.currentTarget.dataset.item;
    if (item.is_my !== 1 && this.data.fromTpl) {
      if (!this.data.isMaster) {
        app.util.navigateTo(`common/component/universal-card/card-show?cardid=${this.data.masterInfo.id}&openid=${this.data.masterInfo.openid}`);
      } else if (this.data.guestRecord) {
        app.util.navigateTo(`common/component/universal-card/pages/customer-info/customer-info?id=${this.data.guestRecord.id}`);
      }
    }
  },

  checkAuth() {
    getUserInfo()
      .then((res) => {
        cardUserInfo = res;
      })
      .catch(res => {
        this.setData({
          showGetUserInfo: true,
        });
      });
  },
});

function connect() {
  wx.connectSocket({
    url: wssUrl,
    success: function (res) {
      console.log('socket连接成功');
    },
    fail: function (err) {
      console.log('socket连接失败：', err);
    },
  });
}

function throttle(fn, gapTime) { // 函数节流
  if (gapTime == null) {
    gapTime = 1500;
  }

  let _lastTime = null; // 返回新的函数
  return function () {
    let _nowTime = Number(new Date());
    if (_nowTime - _lastTime > gapTime || !_lastTime) {
      fn.apply(this, arguments);   // 将this和参数传给原函数
      _lastTime = _nowTime;
    }
  };
}

function isJsonStr(str) {
  try {
    if (typeof JSON.parse(str) === 'object') {
      return true;
    }
  } catch (e) {
  }
  return false;
}

function getSystemInfo() {
  wx.getSystemInfo({
    success: (res) => {
      let [system, version] = res.system.split(' ');
      system === 'Android' && Number(version.split('.')[0]) <= 5 && this.setData({ oldAndroid: true });
    },
  });
}
